package com.hutao.manage.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DateUtil {

	private static SimpleDateFormat dateFormat;

	/**
	 * 字符串转换为date
	 * 
	 * @param format  格式花样�?
	 * @param strDate 时间字符�?
	 * @return
	 * @throws ParseException
	 */
	public static Date strToDate(String format, String strDate) throws ParseException {
		dateFormat = new SimpleDateFormat(format);
		return dateFormat.parse(strDate);

	}

	public static String DateToStr(String format, Date date) throws Exception {
		dateFormat = new SimpleDateFormat(format);
		String strDate = dateFormat.format(date);
		return strDate;
	}

	/**
	 * 根据当前月获取上一月信息
	 * 
	 * @param nowMonth
	 * @return
	 */
	public static String getPreMonth(Date nowMonth) {
		Calendar c = Calendar.getInstance();
		c.setTime(nowMonth);
		c.add(Calendar.MONTH, -1);
		return DateUtil.dateFormat("yyyy年MM月", c.getTime());
	}

	/**
	 * 获取指定年月的第一天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static String getFirstDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		cal.set(Calendar.MONTH, month - 1);
		// 获取某月最小天数
		int firstDay = cal.getMinimum(Calendar.DATE);
		// 设置日历中月份的最小天数
		cal.set(Calendar.DAY_OF_MONTH, firstDay);
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(cal.getTime());
	}

	/**
	 * 获取指定年月的最后一天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static String getLastDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		// 设置年份
		cal.set(Calendar.YEAR, year);
		// 设置月份
		cal.set(Calendar.MONTH, month - 1);
		// 获取某月最大天数
		int lastDay = cal.getActualMaximum(Calendar.DATE);
		// 设置日历中月份的最大天数
		cal.set(Calendar.DAY_OF_MONTH, lastDay);
		// 格式化日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(cal.getTime());
	}

	/**
	 * 某一个月第一天和最后一天
	 * 
	 * @param date             指定日期
	 * @param pattern          日期格式
	 * @param isNeedHms是否需要时分秒
	 * @return
	 */
	public static Map<String, Object> getFirstLastDayByMonth(Date date, String pattern, boolean isNeedHms) {
		SimpleDateFormat df = new SimpleDateFormat(pattern);
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(date);
		Date theDate = calendar.getTime();

		// 第一天
		GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
		gcLast.setTime(theDate);
		gcLast.set(Calendar.DAY_OF_MONTH, 1);
		String day_first = df.format(gcLast.getTime());
		StringBuffer str = new StringBuffer().append(day_first);
		if (isNeedHms)
			str.append(" 00:00:00");
		day_first = str.toString();

		// 最后一天
		calendar.add(Calendar.MONTH, 1); // 加一个月
		calendar.set(Calendar.DATE, 1); // 设置为该月第一天
		calendar.add(Calendar.DATE, -1); // 再减一天即为上个月最后一天
		String day_last = df.format(calendar.getTime());
		StringBuffer endStr = new StringBuffer().append(day_last);
		if (isNeedHms)
			endStr.append(" 23:59:59");
		day_last = endStr.toString();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("first", day_first);
		map.put("last", day_last);
		return map;
	}

	/**
	 * 根据当前月获取上一月信息
	 * 
	 * @param nowMonth
	 * @return
	 */
	public static String getPreYearMonth(Date nowMonth) {
		Calendar c = Calendar.getInstance();
		c.setTime(nowMonth);
		c.add(Calendar.YEAR, -1);
		return DateUtil.dateFormat("yyyy年MM月", c.getTime());
	}

	/**
	 * date_format yyyy-MM-dd
	 */
	public static final String DATE_FORMATE = "yyyy-MM-dd";

	/**
	 * date_time_format yyyy-MM-dd HH:mm:ss
	 */
	public static final String DATE_TIME_FORMATE = "yyyy-MM-dd HH:mm:ss";

	/**
	 * time_format HH:mm:ss
	 */
	public static final String TIME_FORMATE = "HH:mm:ss";

	/**
	 * millis of second
	 */
	public static final long MILLIS_SECOND = 1000;

	/**
	 * millis of minute
	 */
	public static final long MILLIS_MINUTE = MILLIS_SECOND * 60;

	/**
	 * millis of hour
	 */
	public static final long MILLIS_HOUR = MILLIS_MINUTE * 60;

	/**
	 * millis of day
	 */
	public static final long MILLIS_DAY = MILLIS_HOUR * 24;

	/**
	 * Downward days
	 * 
	 * @param startDateTime
	 * @param endDateTime
	 * @return days
	 */
	public static int getDaysBetweenOfDownward(Date startDateTime, Date endDateTime) {
		long diffMillis = Math.abs(endDateTime.getTime() - startDateTime.getTime());
		long daysBetween = diffMillis / MILLIS_DAY;
		return Integer.parseInt(String.valueOf(daysBetween));
	}

	/**
	 * Upward days
	 * 
	 * @param startDateTime
	 * @param endDateTime
	 * @return days
	 */
	public static int getDaysBetweenOfUpward(Date startDateTime, Date endDateTime) {

		long diffMillis = Math.abs(endDateTime.getTime() - startDateTime.getTime());
		long daysBetween = diffMillis % MILLIS_DAY == 0 ? diffMillis / MILLIS_DAY : diffMillis / MILLIS_DAY + 1;
		return Integer.parseInt(String.valueOf(daysBetween));
	}

	/**
	 * diff days
	 * 
	 * @param startDate
	 * @param endDate
	 * @return days
	 * @throws ParseException
	 */
	public static int getDaysBetween(Date startDate, Date endDate) throws ParseException {

		long diffMillis = Math.abs(dateTimeConvert(endDate).getTime() - dateTimeConvert(startDate).getTime());
		long daysBetween = diffMillis / MILLIS_DAY;
		return Integer.parseInt(String.valueOf(daysBetween));
	}

	/**
	 * date to str
	 * 
	 * @param format
	 * @param date
	 * @return str
	 */
	public static String dateFormat(String format, Date date) {
		dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	/**
	 * date/datetime/time to str yyyy-MM-dd
	 * 
	 * @param format
	 * @param date
	 * @return str
	 */
	public static String dateFormat(Date date) {
		dateFormat = new SimpleDateFormat(DATE_FORMATE);
		return dateFormat.format(date);
	}

	/**
	 * string to date/datetime/time
	 * 
	 * @param format
	 * @param str
	 * @return date/datetime/time
	 * @throws ParseException
	 */
	public static Date dateParse(String format, String str) throws ParseException {
		dateFormat = new SimpleDateFormat(format);
		return dateFormat.parse(str);
	}

	/**
	 * string to date/datetime/time
	 * 
	 * @param str
	 * @return date/datetime/time yyyy-MM-dd
	 * @throws ParseException
	 */
	public static Date dateParse(String str) throws ParseException {
		dateFormat = new SimpleDateFormat(DATE_FORMATE);
		return dateFormat.parse(str);
	}

	/**
	 * datetime to date
	 * 
	 * @param dateTime
	 * @return date
	 * @throws ParseException
	 */
	public static Date dateTimeConvert(Date dateTime) throws ParseException {
		return dateParse(dateFormat(dateTime));
	}

	public static int compare(Date firstDate, Date secondDate) throws ParseException {
		return dateParse(dateFormat(firstDate)).compareTo(dateParse(dateFormat(secondDate)));

	}
	
	/**
	 * 计算
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static int getTimeDifferenceDays(long d1,long d2) {
		
		Integer dyas = (int) ((d1 - d2) / 1000 / 3600 / 24);
		if (dyas <= 1&&dyas > 0) {
			dyas = 1;
		}
		return dyas;
	}
	
	
	public static List<String> getMonthBetween(Date minDate, Date maxDate) throws ParseException {
	    ArrayList<String> result = new ArrayList<String>();
	    SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM");//格式化为年月
 
	    Calendar min = Calendar.getInstance();
	    Calendar max = Calendar.getInstance();
 
	    min.setTime(minDate);
	    min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
 
	    max.setTime(maxDate);
	    max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
 
	    Calendar curr = min;
	    while (curr.before(max)) {
	     result.add(sdf.format(curr.getTime()));
	     curr.add(Calendar.MONTH, 1);
	    }
	    min = null;max = null;curr = null;
	    return result;
	  }
	
	
	
	public static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
	    ArrayList<String> result = new ArrayList<String>();
	    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化为年月
 
	    Calendar min = Calendar.getInstance();
	    Calendar max = Calendar.getInstance();
 
	    min.setTime(sdf.parse(minDate));
	    min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
 
	    max.setTime(sdf.parse(maxDate));
	    max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
 
	    Calendar curr = min;
	    while (curr.before(max)) {
	     result.add(sdf.format(curr.getTime()));
	     curr.add(Calendar.MONTH, 1);
	    }
	    min = null;max = null;curr = null;
	    return result;
	  }
	
	
	public static int getXiangChaDays(long bigHaoMiao, long xiaoHaoMiao) {
		Integer dyas = (int) ((bigHaoMiao - xiaoHaoMiao) / 1000 / 3600 / 24);
		if (dyas <= 1&&dyas > 0) {
			dyas = 1;
		}

		return dyas;
	}
	
	
	/**
	 * 获取当月有多少天
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getMonthDays(int year,int month) {
		int days=0;
		//先判断闰年，然后的话再考虑1-12月某个月是多少天
		switch(month){
			case 1:case 3:case 5:case 7:case 8:case 10:case 12:days = 31;break;
			case 4:case 6:case 9:case 11:days = 30;break;
			case 2:{
				if(year%400==0 || year%4==0 && year%100!=0){
					days = 29;
				}else{
					days = 28;
				}
			}
		}
		return days;
        
    }
	
	
	
	public static String getYearMonthStr(String dateStr) {
		
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
			Date date = sdf.parse(dateStr);
			return sdf.format(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
		
	}
	
	
	public static void main(String[] args) {
		System.out.println(getYearMonthStr("2019-12-01 00:12:23"));
	}


	
	
}
